package com.tanhua.server.service;

import com.tanhua.commons.exception.TanHuaException;
import com.tanhua.domain.db.*;
import com.tanhua.domain.vo.*;
import com.tanhua.dubbo.api.db.*;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author Jyz
 * @Date 2021/8/23 - 12:56
 * @Description com.tanhua.server.service
 * @Since version-11
 */
@Service
public class TestSoulService {
    /* @Reference
     private SoultestPaperApi soultestPaperApi;//试卷操作api
     @Reference
     private SoultestQuestionApi soultestQuestionApi;//问题操作api
     @Reference
     private SoultestOptionApi soultestOptionApi;//选项操作api
     @Reference
     private SoultestResultApi soultestResultApi;//结果操作api
     @Reference
     private SoultestConclusionApi soultestConclusionApi;//结果鉴定描述操作api*/
    @Reference
    private UserInfoApi userInfoApi;//用户详细信息操作api
    @Reference
    private TestSoulApi testSoulApi;//灵魂测试操作api

    /**
     * 展示列表
     *
     * @return
     */
    public List<PaperLinkedVo> testSoul() {
        //获得当前用户id
        Long userId = UserHolder.getUserId();
        List<PaperLinkedVo> paperLinkedVoList = new ArrayList<>();
        //获得试卷的集合 方法-搜所有返回集合
        List<SoultestPaper> paperList = testSoulApi.getPaper();
        //正常不用判断，不可能没试卷除非查错
        if (paperList == null) {
            throw new TanHuaException("暂时无法测试");
        }
        //遍历试卷集合，获得单个对象
        for (SoultestPaper soultestPaper : paperList) {
            PaperLinkedVo paperLinkedVo = new PaperLinkedVo();
            //把paper上有的数据都存vo里
            BeanUtils.copyProperties(soultestPaper, paperLinkedVo);
            paperLinkedVo.setId(soultestPaper.getId().toString());
            paperLinkedVo.setStar(soultestPaper.getStar().intValue());
            //用paper的id去下一张表查当前这张试卷的题目
            Long paperId = soultestPaper.getId();
            //获得题目集合，和试卷查发一样，多个eq条件
            List<SoultestQuestion> questionList = testSoulApi.getQuestions(paperId);
            List<QuestionsVo> questionsVoList = new ArrayList<>();
            //遍历题目，获得单个题目对象
            for (SoultestQuestion soultestQuestion : questionList) {
                //题目对象的值存题目对象vo里
                QuestionsVo questionsVo = new QuestionsVo();
                questionsVo.setId(soultestQuestion.getId().toString());
                questionsVo.setQuestion(soultestQuestion.getQuestion());
                //根据用户题目id查询选项表 返回选项表集合
                List<SoultestOption> optionList = testSoulApi.queryOptionListByQuestionId(soultestQuestion.getId());
                //定义集合存储选项表每个选项内容
                List<OptionsVo> optionsVoList = new ArrayList<>();
                //遍历查出来的选项集合，吧数据存选项的vo里
                for (SoultestOption soultestOption : optionList) {
                    OptionsVo optionsVo = new OptionsVo();
                    optionsVo.setId(soultestOption.getId().toString());
                    optionsVo.setOption(soultestOption.getOptionContent());
                    optionsVoList.add(optionsVo);
                }
                //将添加好的选项集合存储到问题vo里
                questionsVo.setOptions(optionsVoList);
                //每遍历一个问题  就需要添加到List<问题vo>属性
                questionsVoList.add(questionsVo);

                //根据当前用户、当前试卷id查询报告表 如果能查到记录 就将报告表id赋值给当前试卷的id
                SoultestResult soultestResult = testSoulApi.getResult(userId, soultestPaper.getId());
                if (soultestResult != null) {
                    paperLinkedVo.setReportId(soultestResult.getId().toString());
                }
                //再去查报告表的试卷id，不管存多少次，解锁条件看最大的那个试卷id。
                SoultestResult paperResult = testSoulApi.getBigPaperId(userId);
                if (paperResult != null) {
                    //判断最大那个试卷id+1是不是大于当前试卷id（+1是因为做完以后下一张可以解锁，最大试卷id+1，就是要做的下一张试卷的id），然后来设定该试卷是否解锁
                    paperLinkedVo.setIsLock(paperResult.getPaperId() + 1 >= soultestPaper.getId() ? 0 : 1);
                } else if (soultestPaper.getId() == 1) {
                    paperLinkedVo.setIsLock(0);
                } else {
                    paperLinkedVo.setIsLock(1);
                }
            }
//          //最后就把要的数据都存好，然后返回就好
            paperLinkedVo.setQuestions(questionsVoList);
            paperLinkedVoList.add(paperLinkedVo);
        }
        return paperLinkedVoList;
    }

    /**
     * 提交问卷
     *
     * @param answers
     * @return
     */
    public String postMapper(List<Map> answers) {
        // answers列表里是map,每一对map对应的就是问题和得分
        //四个得分
        int extroScore = 0;
        int decideScore = 0;
        int abstractScore = 0;
        int reasonScore = 0;
        //获取一下试卷的ID
        Object questionId = answers.get(0).get("questionId");
        //断言 获取到的试卷试卷Id不为null 为null就会报错
        assert questionId != null;
        Integer questionIntId = Integer.parseInt(questionId + "");
        //根据问题id查询问题表 获取试卷id
        SoultestQuestion soultestQuestion = testSoulApi.queryQuestionById(questionIntId.longValue());
        SoultestResult result = new SoultestResult();

        //设置报告对象的试卷id
        int paperId = soultestQuestion.getPaperId().intValue();
        for (Map map : answers) {
            Object optionId = map.get("optionId");
            //断言不为选项id不为null
            assert optionId != null;
            int optionIntId = Integer.parseInt(optionId + "");
            //调用api获取选项对象
            SoultestOption soultestOption = testSoulApi.querySoulOptionById(optionIntId);
            //计算+
            decideScore += soultestOption.getAbstractScore().intValue();
            abstractScore += soultestOption.getDecideScore().intValue();
            extroScore += soultestOption.getExtroScore().intValue();
            reasonScore += soultestOption.getReasonScore().intValue();
        }
        //判断哪个分数最高
        int max = Math.max(extroScore, decideScore);
        int max1 = Math.max(max, abstractScore);
        int max2 = Math.max(max1, reasonScore);
        //定义一个对象 存储鉴定的类型
        int type;
        //判断
        if (max2 == abstractScore) {//如果最大值是抽象类型
            type = 1;
        } else if (max2 == decideScore) {//如果最大值是判断类型
            type = 2;
        } else if (max2 == extroScore) {//如果最大值是外向类型
            type = 3;
        } else {//如果最大值是理性类型
            type = 4;
        }
        //统一在这里进行赋值
        result.setUserId(UserHolder.getUserId().intValue());//用户
        result.setPaperId(paperId);//试卷id
        result.setAbstractScore(abstractScore);//抽象类型
        result.setDecideScore(decideScore);//判断类型
        result.setExtroScore(extroScore);//外向类型
        result.setReasonScore(reasonScore);//理性类型
        result.setType(type);//鉴定的类型
        //调用saveOrUpdate方法 传入一个result对象 执行更新或者保存的方法 返回报告id
        return testSoulApi.saveOrUpdate(result);
    }

    /**
     * 查看结果
     *
     * @param resultId
     * @return
     */
    public SoulResultVo getReport(Long resultId) {
        //根据前端提供的报告id查询报告内容
        SoultestResult soultestResult = testSoulApi.getById(resultId);
        Long type = soultestResult.getType().longValue();
        //从结果的类型里查类型的描述和图片，然后封装到vo
        SoultestConclusion soultestConclusion = testSoulApi.getConclusion(type);
        SoulResultVo soulResultVo = new SoulResultVo();
        soulResultVo.setConclusion(soultestConclusion.getTxt());
        soulResultVo.setCover(soultestConclusion.getCover());
        //(下面这个方法 抽取了代码 实际上只是创建了4个vo对象 存储用户的鉴定类型信息)
        List<DimensionsVo> dimensionsVoList = packageUserDimensions(soultestResult);
        soulResultVo.setDimensions(dimensionsVoList);
        //定义一个集合存
        List<SimilarYouVo> similarYouVoList = new ArrayList<>();
        //获取性别
        UserInfo myUserInfo = userInfoApi.queryUserInfo(UserHolder.getUserId());
        String myGender = myUserInfo.getGender();
        String gender;
        if (myGender.equals("woman")){
            gender="man";
        }else {
            gender="woman";
        }
        //用之前得到的类型查原表，找10个类型一样的人，得到集合，取ID
        //用了随机查询的方法，要在mapper里自定义
        List<UserInfo> resultList = testSoulApi.getSimilarYou(type, resultId, soultestResult.getPaperId(),gender);
        //遍历相似用户集合
        if (resultList != null) {
            for (UserInfo userInfo : resultList) {
                //根据相似用户的id分别去查询详细用户 进行封装属性
                SimilarYouVo similarYouVo = new SimilarYouVo();
                similarYouVo.setId(userInfo.getId());
                similarYouVo.setAvatar(userInfo.getAvatar());
                similarYouVoList.add(similarYouVo);
            }
            soulResultVo.setSimilarYou(similarYouVoList);
        }
        return soulResultVo;
    }

    /**
     * 封装用户的类型描述信息
     *
     * @param soultestResult
     * @return
     */
    private List<DimensionsVo> packageUserDimensions(SoultestResult soultestResult) {
        List<DimensionsVo> dimensionsVoList = new ArrayList<>();
        DimensionsVo d1 = new DimensionsVo();
        DimensionsVo d2 = new DimensionsVo();
        DimensionsVo d3 = new DimensionsVo();
        DimensionsVo d4 = new DimensionsVo();
        d1.setKey("外向");
        d2.setKey("判断");
        d3.setKey("抽象");
        d4.setKey("理性");
        dimensionsVoList.add(d1);
        dimensionsVoList.add(d2);
        dimensionsVoList.add(d3);
        dimensionsVoList.add(d4);
        d1.setValue(soultestResult.getReasonScore().toString());
        d2.setValue(soultestResult.getExtroScore().toString());
        d3.setValue(soultestResult.getAbstractScore().toString());
        d4.setValue(soultestResult.getDecideScore().toString());
        return dimensionsVoList;
    }
}
